<?php

declare(strict_types=1);

namespace app\admin\controller;

use think\Request;
use sheep\exception\SheepException;
use sheep\controller\Backend;
use sheep\facade\Auth;
use sheep\model\auth\Admin;
use GuzzleHttp\Client;
use app\shop\model\order\Order;
use app\user\model\User;
use app\shop\model\order\OrderItem;
use app\shop\model\order\Express;

class Test extends Backend
{

    protected $middleware = [
        // 'check_login:admin' => ['except' 	=> ['lists']]
    ];



    public function test(Request $request)
    {
        // 获取用户 openid
        // $user = app('shop.wechat.official_account')->user->get('oMzyA6j15lk8skJHFiZnc-kmAMTw');
        // print_r($user);exit;
        // $userLists = app('shop.wechat.official_account')->user->list();
        // print_r($userLists);
        // exit;



        // 新订单通知
        // $order = Order::find(58);
        // $user = User::find(21);
        // $admins = Admin::where('id', 1)->select();
        // if (!$admins->isEmpty()) {
        //     \yunwuxin\facade\Notification::send(
        //         $admins,
        //         new \app\shop\notification\order\OrderNew([
        //             'order' => $order,
        //             'user' => $user
        //         ])
        //     );
        // }
        // exit;

        // 订单发货通知
        // $order = Order::find(58);
        // $items = $order->items;
        // $express = Express::where('order_id', 58)->find();
        // $user = User::where('id', $order['user_id'])->find();
        // $user && $user->notify(
        //     new \app\shop\notification\order\OrderDispatched([
        //         'order' => $order,
        //         'items' => $items,
        //         'express' => $express,
        //     ])
        // );
        // exit;

        exit;
        // 发送消息通知
        $admin = \app\admin\model\auth\Admin::find(10);
        $admin->notify(new \sheep\notification\Order([
            'aaa' => 'bbb',
            'event' => 'aftersale_change'
        ]));

        exit;


        echo (new \sheep\model\auth\Admin)->getUnifiedToken('admin:11');
        echo (new \sheep\model\user\User)->getUnifiedToken('user:2');
        exit;
        $type = $request->param('type', 'qiniu');

        // $disable_functions = ini_get('disable_functions');
        // $disableFunctions = array_values(array_filter(explode(',', $disable_functions)));
        // print_r($disableFunctions);
        // exit;

        $suffix = $this->suffix($type, [
            "width" => 200,
            "height" => 200,
            "mode" => 'fill',
            "quality" => 90,
            "gravity" => 'south_east'
        ]);

        echo $suffix;



        exit;


        //         \tauthz\facade\Enforcer::addRoleForUser('admin:10', 'super');

        // echo 'ok';exit;

        //         \think\facade\Db::listen(function ($sql) {
        //             echo $sql . '<br>';
        //         });

        //         $groups = \app\admin\model\file\FileGroup::cache('db_file_group_groups', 3600)->column('group');
        //         print_r($groups);
        //         if (!in_array('smallnews1', $groups)) {
        //             $groupData = [
        //                 'name' => 'smallnews1',
        //                 'group' => 'smallnews1'
        //             ];
        //             try {
        //                 (new \app\admin\model\file\FileGroup)->cache('db_file_group_groups')->save($groupData);// 
        //             } catch (\Exception $e) {
        //                 // 捕获异常，并丢弃
        //             }
        //         }


        //         $groups = \app\admin\model\file\FileGroup::cache('db_file_group_groups', 3600)->column('group');
        //         print_r($groups);
        // exit;


        if ($request->isPost()) {
            echo '<pre>';
            $file = $request->file('file');

            // 自定义文件名
            $result = \sheep\facade\Uploader::name(function () {
                return 'smallnews';
            })->upload($file, 'bbb', 'public');

            print_r($result);
        }

        return view('test');
    }


    /**
     * 测试后台websocket 通知是否正常
     *
     * @return void
     */
    public function testWebsocket(Request $request)
    {
        $params = $request->param();
        $receiver_id = $params['receiver_id'] ?? '';
        $type = $params['type'] ?? 'user';
        $websocket = new \sheep\library\Websocket();

        echo '<form method="post" action="?">';
        echo '
                <select name="type">
                    <option value="user" ' . ($type == 'user' ? 'selected' : '') . '>用户</option>
                    <option value="admin" ' . ($type == 'admin' ? 'selected' : '') . '>管理员</option>
                </select>
                <input type="text" name="receiver_id" placeholder="请填写接收用户的 id" value="' . $receiver_id . '" />
                <input type="submit" name="发送" /><br>';

        echo '</form>';

        if (request()->isPost()) {
            if (!$receiver_id) {
                echo '请填写接收用户的 id';
            }

            $data = [
                'receiver' => [
                    'ids' => $receiver_id,
                    'type' => $type
                ],
                'data' => '一条测试消息'
            ];
            $result = $websocket->notification($data);
            if ($result == true) {
                echo '发送成功';
            } else {
                echo '发送失败：' . json_encode($result);
            }
        }
    }



    /**
     * 获取小程序模板 tid 和 kid
     *
     * @param Request $request
     * @return void
     */
    public function miniTemplate(Request $request)
    {
        $params = $request->param();
        $method = $params['method'] ?? '';
        $category_id = $params['category_id'] ?? '';
        $tid = $params['tid'] ?? '';

        $result = app('shop.wechat.mini_program')->subscribe_message->getCategory();

        echo '<form method="get" action="?">';

        if ($result['errcode'] == 0) {
            $categories = $result['data'];
            foreach ($categories as $key => $category) {
                echo "类目ID：" . $category['id'] . "；名称：" . $category['name'] . "<br>";
            }

            echo '<input type="text" name="category_id" placeholder="请填写获取的类目ID" value="' . $category_id . '" />
                <input type="submit" name="获取分类下模板" /><br>';
        } else {
            echo "获取失败：" . json_encode($result);
        }


        if ($category_id) {
            $templatesResult = app('shop.wechat.mini_program')->subscribe_message->getTemplateTitles([$category_id], 0, 30);
            if ($templatesResult['errcode'] == 0) {
                $templates = $templatesResult['data'];
                foreach ($templates as $key => $template) {
                    echo "模板 tid：" . $template['tid'] . "；模板名称：" . $template['title'] . "<br>";
                }

                echo '<input type="text" name="tid" placeholder="请填写获取的模板 tid" value="' . $tid . '" />
                <input type="hidden" name="method" value="get_template" />
                <input type="submit" name="获取模板字段" /><br>';
            } else {
                echo "模板获取失败：" . json_encode($templatesResult);
            }
        }

        echo '</form>';

        if ($tid) {
            $templateResult = app('shop.wechat.mini_program')->subscribe_message->getTemplateKeywords((string)$tid);
            if ($templateResult['errcode'] == 0) {
                $templates = $templateResult['data'];
                foreach ($templates as $key => $template) {
                    echo "模板字段 kid：" . $template['kid'] . "；字段名称：" . $template['name'] . "；示例值：" . $template['example'] . "<br>";
                }
            } else {
                echo "模板字段获取失败：" . json_encode($templateResult);
            }
        }
    }


    public function initData()
    {
        $type = request()->param('type');
        if (!$type) {
            echo "请传入要初始化数据的 type，支持的值有" . "<br>";
            echo "------------------------<br>";
            echo "all:全部更新" . "<br>";
            echo "area:地区表" . "<br>";
            echo "express:快递公司表" . "<br>";
            echo "richtext:富文本表" . "<br>";
            echo "page:前端路由表" . "<br>";
            echo "access:权限表" . "<br>";
            echo "config:配置表" . "<br>";
            exit;
        }

        if ($type == 'area' || $type == 'all') {
            // data area 存文件
            $dataAreaFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitDataArea.php';

            // 获取数据库中的配置
            $areas = \app\shop\model\data\Area::select()->toArray();
            $areas = var_export_short($areas, true);

            file_put_contents($dataAreaFile, '<?php' . "\n\nreturn " . $areas . ";\n");
            echo "area 初始化数据更新成功" . "<br>";

            if ($type == 'area') {
                exit;
            }
        }

        if ($type == 'express' || $type == 'all') {
            // data express 存文件
            $dataExpressFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitDataExpress.php';

            // 获取数据库中的配置
            $expresses = \app\shop\model\data\Express::select()->toArray();
            $expresses = var_export_short($expresses, true);

            file_put_contents($dataExpressFile, '<?php' . "\n\nreturn " . $expresses . ";\n");
            echo "express 初始化数据更新成功" . "<br>";

            if ($type == 'express') {
                exit;
            }
        }

        if ($type == 'richtext' || $type == 'all') {
            // data richtext 存文件
            $dataExpressFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitDataRichtext.php';

            // 获取数据库中的配置
            $expresses = \app\shop\model\data\Richtext::select()->toArray();
            $expresses = var_export_short($expresses, true);

            file_put_contents($dataExpressFile, '<?php' . "\n\nreturn " . $expresses . ";\n");
            echo "richtext 初始化数据更新成功" . "<br>";

            if ($type == 'richtext') {
                exit;
            }
        }

        if ($type == 'page' || $type == 'all') {
            // data page 存文件
            $dataPageFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitDataPage.php';

            // 获取数据库中的配置
            $pages = \app\shop\model\data\Page::select()->each(function ($page) {
                $page->origin_create_time = $page->getData('create_time');
                $page->origin_update_time = $page->getData('update_time');
            })->toArray();
            foreach ($pages as &$page) {
                $page['create_time'] = $page['origin_create_time'];
                $page['update_time'] = $page['origin_update_time'];
                unset($page['id'], $page['origin_create_time'], $page['origin_update_time']);
            }
            $pages = var_export_short($pages, true);

            file_put_contents($dataPageFile, '<?php' . "\n\nreturn " . $pages . ";\n");
            echo "page 初始化数据更新成功" . "<br>";

            if ($type == 'page') {
                exit;
            }
        }

        if ($type == 'access' || $type == 'all') {
            // access 存文件
            $accessFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitAccess.php';

            // 获取数据库中的配置
            $accesses = \think\facade\Db::table(config('database.connections.mysql.prefix') . 'access')->select()->toArray();
            $accesses = var_export_short($accesses, true);

            file_put_contents($accessFile, '<?php' . "\n\nreturn " . $accesses . ";\n");
            echo "access 初始化数据更新成功" . "<br>";

            if ($type == 'access') {
                exit;
            }
        }

        if ($type == 'config' || $type == 'all') {
            $configFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'InitConfig.php';
            $configs = \app\admin\model\config\Config::select()->toArray();

            if (file_exists($configFile)) {
                $fileConfig = include $configFile;
                $fileConfig = array_column($fileConfig, null, 'code');

                foreach ($configs as $key => &$config) {
                    $config['value'] = isset($fileConfig[$config['code']]) ? $fileConfig[$config['code']]['value'] : $config['value'];
                }
            }

            $configs = var_export_short($configs, true);

            file_put_contents($configFile, '<?php' . "\n\nreturn " . $configs . ";\n");
            echo "config 初始化数据更新成功" . "<br>";

            if ($type == 'config') {
                exit;
            }
        }
    }



    public function testData()
    {
        $type = request()->param('type');
        if (!$type) {
            echo "请传入要初始化数据的 type，支持的值有" . "<br>";
            echo "------------------------<br>";
            echo "all:全部更新" . "<br>";
            echo "goods:商品表" . "<br>";
            exit;
        }

        if ($type == 'goods' || $type == 'all') {
            $testGoodsFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestGoods.php';

            // 获取数据库中的配置
            $goods = \app\shop\model\goods\Goods::select()->toArray();
            $goods = var_export_short($goods, true);

            file_put_contents($testGoodsFile, '<?php' . "\n\nreturn " . $goods . ";\n");
            echo "goods 初始化数据更新成功" . "<br>";

            if ($type == 'goods') {
                exit;
            }
        }
        if ($type == 'goods_sku' || $type == 'all') {
            $testGoodsSkuFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestGoodsSku.php';

            // 获取数据库中的配置
            $goodsSku = \app\shop\model\goods\Sku::select()->toArray();
            $goodsSku = var_export_short($goodsSku, true);

            file_put_contents($testGoodsSkuFile, '<?php' . "\n\nreturn " . $goodsSku . ";\n");
            echo "goods sku 初始化数据更新成功" . "<br>";

            if ($type == 'goods_sku') {
                exit;
            }
        }

        if ($type == 'goods_sku_price' || $type == 'all') {
            $testGoodsSkuPriceFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestGoodsSkuPrice.php';

            // 获取数据库中的配置
            $goodsSkuPrice = \app\shop\model\goods\SkuPrice::select()->toArray();
            $goodsSkuPrice = var_export_short($goodsSkuPrice, true);

            file_put_contents($testGoodsSkuPriceFile, '<?php' . "\n\nreturn " . $goodsSkuPrice . ";\n");
            echo "goods sku price 初始化数据更新成功" . "<br>";

            if ($type == 'goods_sku_price') {
                exit;
            }
        }

        if ($type == 'goods_service' || $type == 'all') {
            $testGoodsServiceFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestGoodsService.php';

            // 获取数据库中的配置
            $goodsService = \app\shop\model\goods\Service::select()->toArray();
            $goodsService = var_export_short($goodsService, true);

            file_put_contents($testGoodsServiceFile, '<?php' . "\n\nreturn " . $goodsService . ";\n");
            echo "goods service 初始化数据更新成功" . "<br>";

            if ($type == 'goods_service') {
                exit;
            }
        }

        if ($type == 'category' || $type == 'all') {
            $testCategoryFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestCategory.php';

            // 获取数据库中的配置
            $category = \app\shop\model\Category::select()->toArray();
            $category = var_export_short($category, true);

            file_put_contents($testCategoryFile, '<?php' . "\n\nreturn " . $category . ";\n");
            echo "goods category 初始化数据更新成功" . "<br>";

            if ($type == 'category') {
                exit;
            }
        }

        if ($type == 'data_faq' || $type == 'all') {
            $testDataFaqFile = app()->getRootPath() . 'database' . DIRECTORY_SEPARATOR . 'seeds' . DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR . 'TestDataFaq.php';

            // 获取数据库中的配置
            $faq = \app\shop\model\data\Faq::select()->toArray();
            $faq = var_export_short($faq, true);

            file_put_contents($testDataFaqFile, '<?php' . "\n\nreturn " . $faq . ";\n");
            echo "data faq 初始化数据更新成功" . "<br>";

            if ($type == 'data_faq') {
                exit;
            }
        }
    }


    /**
     * 获取图片后缀
     * 
     * @param string $type aliyun|qcloud|qiniu
     * @param array $params 参数，包含宽高，mode
     */
    private function suffix($type, $params = [])
    {
        $width = $params['width'];          // 宽度
        $height = $params['height'];        // 高度
        $mode = $params['mode'] ?? 'fill';            // 缩放模式
        $quality = $params['quality'] ?? 90;      // 压缩质量
        $gravity = $params['gravity'] ?? 'center';      // 裁剪位置

        $suffix = '';
        switch ($type) {
            case 'aliyun':
                // 裁剪
                $crop_str = '';
                if (!empty($gravity) && $gravity != 'center') {
                    // 指定了裁剪区域
                    $mode = 'mfit';
                    $crop_str = '/crop,g_' . $this->gravityFormat($type, $gravity) . ',w_' . $width . ',h_' . $height;
                }

                // 质量压缩
                if ($quality > 0 && $quality < 100) {
                    $quality_str = '/quality,q_' . $quality;
                }

                // 缩放参数
                $suffix = 'x-oss-process=image/resize,m_' . $mode . ',w_' . $width . ',h_' . $height;

                // 拼接裁剪和质量压缩
                $suffix .= $crop_str . $quality_str;
                break;
            case 'qcloud':
                $crop_str = '';
                $mode_str = 'thumbnail';

                if ($mode == 'fill' || (!empty($gravity) && $gravity != 'center')) {
                    // 指定了裁剪区域
                    $mode_str = 'crop';
                    $mode = 'fill';
                    $crop_str = '/gravity/' . $this->gravityFormat($type, $gravity);
                }

                // 质量压缩
                if ($quality > 0 && $quality < 100) {
                    $quality_str = '/rquality/' . $quality;
                }

                $size = $width . 'x' . $height;
                switch ($mode) {
                    case 'lfit':
                        $size = '' . $size . '>';
                        break;
                    case 'mfit':
                        $size = '!' . $size . 'r';
                    case 'fill':
                        break;
                    case 'pad':
                        $size = $size . '/pad/1';
                        break;
                    case 'fixed':
                        $size = $size . '!';
                        break;
                }

                $suffix = 'imageMogr2/' . $mode_str . '/' . $size . $crop_str . $quality_str;
                break;
            case 'qiniu':
                $crop_str = '';
                $size = $width . 'x' . $height;

                if ($mode == 'fill' || (!empty($gravity) && $gravity != 'center')) {
                    // 指定了裁剪区域,全部转为 mfit
                    $mode = 'mfit';
                    $crop_str = '/gravity/' . $this->gravityFormat($type, $gravity) . '/crop/' . $size;
                }

                // 质量压缩
                if ($quality > 0 && $quality < 100) {
                    $quality_str = '/quality/' . $quality;
                }

                switch ($mode) {
                    case 'lfit':
                    case 'pad':     // 七牛不支持在缩放之后，尺寸不足时，填充背景色,所以这里和 lfit 模式一样
                        $size = $size . '>';
                        break;
                    case 'mfit':
                        $size = '!' . $size . 'r';
                        break;
                    case 'fill':
                        // 会被转为 mfit
                        break;
                    case 'fixed':
                        $size = $size . '!';
                        break;
                }

                $suffix = 'imageMogr2/thumbnail/' . $size . $crop_str . $quality_str;
                break;
        }

        return $suffix;
    }


    /**
     * 裁剪区域格式转换
     * 
     * @param string $type aliyun|qcloud|qiniu
     * @param string $gravity 统一的裁剪区域字符
     * 
     * @return string
     */
    private function gravityFormat($type, $gravity)
    {
        $aliyun = [
            'north_west' => 'nw',               // 左上
            'north' => 'north',                 // 中上
            'north_east' => 'ne',               // 右上
            'west' => 'west',                   // 左中
            'center' => 'center',               // 中部
            'east' => 'east',                   // 右中
            'south_west' => 'sw',               // 左下
            'south' => 'south',                 // 中下
            'south_east' => 'se',               // 右下
        ];

        return $type == 'aliyun' ? $aliyun[$gravity] : ($type == 'qiniu' ? \think\helper\Str::studly($gravity) : str_replace('_', '', $gravity));
    }




    /**
     * 异步执行方法
     */
    public function async()
    {
        // \Baiy\ThinkAsync\Facade\Async::exec(self::class, 'execMethod', ['type' => 'exec']);

        \Baiy\ThinkAsync\Facade\Async::execUseCustomQueue(self::class, 'execMethod', 'async_custom', ['type' => 'exec']);


        // $result = \Baiy\ThinkAsync\Facade\Async::queue();
        // print_r($result);
    }


    /**
     * 要执行的方法
     */
    public static function execMethod($param)
    {
        $dir = root_path('runtime/temp');
        @mkdir($dir, 755);

        // 写入日志文件
        $filename = root_path('runtime/temp') . 'async.log';
        file_put_contents($filename, date('Y-m-d H:i:s') . json_encode($param));
    }


    /**
     * 权限节点添加
     *
     * @param  \think\Request  $request
     * @return \think\Response
     */
    public function save(Request $request)
    {
        Auth::guard('user')->user();
        Auth::guard('user')->user();
        Auth::guard('user')->user();
        Auth::guard('user')->user();
        // $token = \xptech\jwt\facade\JwtAuth::builder([
        //     'type' => 'user',
        //     'uid' => 1,
        // ]);
        // print_r($token);exit;

        // $user = Auth::guard('user')->user();
        // print_r($user);
        // exit;
        // $token = \xptech\jwt\facade\JwtAuth::auth();
        // print_r($token);
        // exit;

        // $token = Auth::user();
        // echo $token;
        // exit;

        $result = ['code' => 0, 'msg' => '服务器异常，请重试', 'data' => Auth::guard('user')->user()];
        return json($result);
    }
}
